﻿using System;
using System.Linq;
using System.Collections.Generic;
using Eagles.Base;
using Eagles.Application.Model;
using Eagles.Application.Model.Common;
using Eagles.DomainService.Model.Order;
using Eagles.Interface.Core.Score;
using Eagles.Interface.DataAccess.Util;
using Eagles.Interface.DataAccess.ScoreAccess;
using Eagles.Interface.DataAccess.ProductAccess;
using Eagles.Application.Model.Score.GetScoreRank;
using Eagles.Application.Model.Score.AppScoreExchange;
using Eagles.Application.Model.Score.GetScoreExchangeLs;

namespace Eagles.DomainService.Core.Score
{
    public class ScoreHandler : IScoreHandler
    {
        private readonly IScoreAccess iScoreAccess;
        private readonly IProductAccess iproductAccess;
        private readonly IUtil util;

        public ScoreHandler(IScoreAccess iScoreAccess, IProductAccess iproductAccess, IUtil util)
        {
            this.iScoreAccess = iScoreAccess;
            this.iproductAccess = iproductAccess;
            this.util = util;
        }

        /// <summary>
        /// 积分兑换接口
        /// </summary>
        /// <param name="request"></param>
        /// <returns></returns>
        public AppScoreExchangeResponse AppScoreExchange(AppScoreExchangeRequest request)
        {
            var response = new AppScoreExchangeResponse();
            var now = DateTime.Now;
            var tokens = util.GetUserId(request.Token, 0);
            if (tokens == null || tokens.UserId <= 0)
                throw new TransactionException(MessageCode.InvalidToken, MessageKey.InvalidToken);
            var userInfo = util.GetUserInfo(tokens.UserId);
            if (userInfo == null)
                throw new TransactionException(MessageCode.InvalidToken, MessageKey.InvalidToken);
            if (request.Count <= 0)
                throw new TransactionException(MessageCode.InvalidParameter, MessageKey.InvalidParameter);
            try
            {
                try
                {
                    //并发控制
                    var reisSucc = iproductAccess.AddUniqueUser(userInfo.UserId);
                    if (reisSucc == 0)
                        throw new TransactionException(MessageKey.ExchangeMax, MessageKey.ExchangeMax);
                }
                catch (Exception)
                {
                    throw new TransactionException(MessageKey.ExchangeMax, MessageKey.ExchangeMax);
                }
                //查询商品
                var productInfo = iproductAccess.GetProductDetail(request.ProductId);
                if (productInfo == null)
                    throw new TransactionException(MessageCode.ProductNotExists, MessageKey.ProductNotExists);
                var startDate = productInfo.BeginTime;
                var endDate = productInfo.EndTime;
                if(!(now.CompareTo(startDate) >= 0 && now.CompareTo(endDate) <= 0))
                    throw new TransactionException(MessageCode.NotExchangDate, MessageKey.NotExchangDate);
                var buyCount = request.Count; //购买数量
                var prodName = productInfo.ProdName; //商品名称
                var score = productInfo.Score; //商品积分
                var stock = productInfo.Stock; //库存
                var maxBuyCount = productInfo.MaxBuyCount; //每人最大购买数量
                var userCount = iproductAccess.GetOrderByProduct(request.ProductId, userInfo.UserId); //用户实际购买数量
                if (maxBuyCount < userCount || maxBuyCount < buyCount + userCount)
                    throw new TransactionException(MessageCode.LimitedCount, MessageKey.LimitedCount);
                var userScore = userInfo.Score; //用户积分
                if (stock < buyCount)
                    throw new TransactionException(MessageCode.NoInventory, MessageKey.NoInventory);
                if (userScore < score * request.Count)
                    throw new TransactionException(MessageCode.InsufficientScore, MessageKey.InsufficientScore);
                var modifyStock = iproductAccess.EditStock(buyCount, request.ProductId);
                if(modifyStock <= 0)
                    throw new TransactionException(MessageCode.NoInventory, MessageKey.NoInventory);
                var order = new TbOrder
                {
                    OrgId = tokens.OrgId,
                    ProdId = request.ProductId,
                    ProdName = prodName,
                    OrderStatus = 0,
                    Score = score,
                    Count = request.Count,
                    Address = request.Address,
                    Province = request.Province,
                    City = request.City,
                    District = request.District,
                    CreateTime = now,
                    UserId = userInfo.UserId
                };
                //订单表、流水表
                var exchange = iScoreAccess.AppScoreExchange(order, userScore, buyCount);
                //更新用户积分
                var result = util.EditUserScore(userInfo.UserId, -score * request.Count);
                if (result <= 0)
                    throw new TransactionException(MessageCode.UpdateScoreFail, MessageKey.UpdateScoreFail);
                return response;
            }
            finally
            {
                iproductAccess.DeleteUniqueUser(userInfo.UserId);
            }
        }

        public GetScoreExchangeLsResponse GetScoreExchangeLs(GetScoreExchangeLsRequest request)
        {
            var response = new GetScoreExchangeLsResponse();
            var tokens = util.GetUserId(request.Token, 0);
            if (tokens == null || tokens.UserId <= 0)
                throw new TransactionException(MessageCode.InvalidToken, MessageKey.InvalidToken);
            if (request.AppId <= 0)
                throw new TransactionException(MessageCode.InvalidParameter, MessageKey.InvalidParameter);
            if (!util.CheckAppId(request.AppId))
                throw new TransactionException(MessageCode.InvalidParameter, MessageKey.InvalidParameter);
            var result = iScoreAccess.GetScoreExchangeLs(tokens.UserId);
            if (result != null && result.Count > 0)
            {
                response.ScoreList = result?.Select(x => new Application.Model.Common.UserScore()
                {
                    Score = x.Score,
                    CreateTime = x.CreateTime.ToString("yyyy-MM-dd HH:mm:ss"),
                    RewardsType = x.RewardsType,
                    Comment = x.Comment,
                    OriScore = x.OriScore
                }).ToList();
            }
            else            
                throw new TransactionException(MessageCode.NoData, MessageKey.NoData);            
            return response;
        }

        public GetScoreRankResponse GetScoreRank(GetScoreRankRequest request)
        {
            var response = new GetScoreRankResponse()
            {
                UserRank = new List<UserRank>(),
                BranchRank = new List<BranchRank>()
            };
            var tokens = util.GetUserId(request.Token, 0);
            if (tokens == null || tokens.UserId <= 0)
                throw new TransactionException(MessageCode.InvalidToken, MessageKey.InvalidToken);
            if (request.AppId <= 0)
                throw new TransactionException(MessageCode.InvalidParameter, MessageKey.InvalidParameter);
            if (!util.CheckAppId(request.AppId))
                throw new TransactionException(MessageCode.InvalidParameter, MessageKey.InvalidParameter);
            var orgInfo = util.GetOrgInfo(request.AppId);
            if (orgInfo == null)
                throw new TransactionException(MessageCode.InvalidParameter, MessageKey.InvalidParameter);
            var userResult = iScoreAccess.GetUserRank(request.AppId);
            if (userResult != null && userResult.Count > 0)
            {
                //总排行
                var userRankList = new List<UserRank>();
                var i = 1;
                userResult?.ForEach(x =>
                {
                    if (i < 11)
                        response.UserRank.Add(new UserRank()
                        {
                            No = i,
                            UserId = x.UserId,
                            UserName = x.Name,
                            BranchName = x.BranchName,
                            Score = x.Score
                        });
                    userRankList.Add(new UserRank()
                    {
                        No = i,
                        UserId = x.UserId,
                        UserName = x.Name,
                        BranchName = x.BranchName,
                        Score = x.Score
                    });
                    i++;
                });
                //个人排行
                var list = userRankList.Where(x => x.UserId == tokens.UserId).ToList();
                response.MyRank = list.Single().No;
            }
            else            
                response.UserRank = null;
            //积分类型
            var rankType = orgInfo.ScoreType;
            response.BranchRankType = rankType;
            var branckResult = iScoreAccess.GetBranchRank(request.AppId, rankType);
            if (branckResult != null && branckResult.Count > 0)
            {
                var j = 1;
                branckResult.ForEach(x =>
                  {
                      response.BranchRank.Add(new BranchRank()
                      {
                          No = j,
                          BranchId = x.BranchId,
                          BranchName = x.BranchName,
                          Score = x.Score
                      });
                      j++;
                  });
            }
            else
                response.BranchRank = null;
            if (userResult == null && branckResult == null)
                throw new TransactionException(MessageCode.NoData, MessageKey.NoData);
            return response;
        }
    }
}